
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Advanced event loops &#8212; libuv documentation</title>
    <link rel="stylesheet" href="../_static/nature.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script src="../_static/jquery.js"></script>
    <script src="../_static/underscore.js"></script>
    <script src="../_static/doctools.js"></script>
    <script src="../_static/language_data.js"></script>
    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Utilities" href="utilities.html" />
    <link rel="prev" title="Processes" href="processes.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="utilities.html" title="Utilities"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="processes.html" title="Processes"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">libuv 1.31.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../guide.html" accesskey="U">User guide</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Advanced event loops</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="advanced-event-loops">
<h1>Advanced event loops<a class="headerlink" href="#advanced-event-loops" title="Permalink to this headline">¶</a></h1>
<p>libuv provides considerable user control over event loops, and you can achieve
interesting results by juggling multiple loops. You can also embed libuv’s
event loop into another event loop based library – imagine a Qt based UI, and
Qt’s event loop driving a libuv backend which does intensive system level
tasks.</p>
<div class="section" id="stopping-an-event-loop">
<h2>Stopping an event loop<a class="headerlink" href="#stopping-an-event-loop" title="Permalink to this headline">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> can be used to stop an event loop. The earliest the loop will
stop running is <em>on the next iteration</em>, possibly later. This means that events
that are ready to be processed in this iteration of the loop will still be
processed, so <code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> can’t be used as a kill switch. When <code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code>
is called, the loop <strong>won’t</strong> block for i/o on this iteration. The semantics of
these things can be a bit difficult to understand, so let’s look at
<code class="docutils literal notranslate"><span class="pre">uv_run()</span></code> where all the control flow occurs.</p>
<p class="rubric">src/unix/core.c - uv_run</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21</pre></div></td><td class="code"><div class="highlight"><pre><span></span>    uv__finish_close(p);
    p = q;
  }
}


int uv_is_closing(const uv_handle_t* handle) {
  return uv__is_closing(handle);
}
<span class="hll">
</span>
int uv_backend_fd(const uv_loop_t* loop) {
  return loop-&gt;backend_fd;
}


int uv_backend_timeout(const uv_loop_t* loop) {
  if (loop-&gt;stop_flag != 0)
<span class="hll">    return 0;
</span>
<span class="hll">  if (!uv__has_active_handles(loop) &amp;&amp; !uv__has_active_reqs(loop))
</span></pre></div>
</td></tr></table></div>
<p><code class="docutils literal notranslate"><span class="pre">stop_flag</span></code> is set by <code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code>. Now all libuv callbacks are invoked
within the event loop, which is why invoking <code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> in them will still
lead to this iteration of the loop occurring. First libuv updates timers, then
runs pending timer, idle and prepare callbacks, and invokes any pending I/O
callbacks. If you were to call <code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> in any of them, <code class="docutils literal notranslate"><span class="pre">stop_flag</span></code>
would be set. This causes <code class="docutils literal notranslate"><span class="pre">uv_backend_timeout()</span></code> to return <code class="docutils literal notranslate"><span class="pre">0</span></code>, which is
why the loop does not block on I/O. If on the other hand, you called
<code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> in one of the check handlers, I/O has already finished and is not
affected.</p>
<p><code class="docutils literal notranslate"><span class="pre">uv_stop()</span></code> is useful to shutdown a loop when a result has been computed or
there is an error, without having to ensure that all handlers are stopped one
by one.</p>
<p>Here is a simple example that stops the loop and demonstrates how the current
iteration of the loop still takes places.</p>
<p class="rubric">uvstop/main.c</p>
<div class="highlight-default notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">#include &lt;stdio.h&gt;</span>
<span class="c1">#include &lt;uv.h&gt;</span>

<span class="n">int64_t</span> <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="n">void</span> <span class="n">idle_cb</span><span class="p">(</span><span class="n">uv_idle_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;Idle callback</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="n">counter</span><span class="o">++</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">counter</span> <span class="o">&gt;=</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
<span class="hll">        <span class="n">uv_stop</span><span class="p">(</span><span class="n">uv_default_loop</span><span class="p">());</span>
</span>        <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;uv_stop() called</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="n">void</span> <span class="n">prep_cb</span><span class="p">(</span><span class="n">uv_prepare_t</span> <span class="o">*</span><span class="n">handle</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s2">&quot;Prep callback</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="nb">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">uv_idle_t</span> <span class="n">idler</span><span class="p">;</span>
    <span class="n">uv_prepare_t</span> <span class="n">prep</span><span class="p">;</span>

    <span class="n">uv_idle_init</span><span class="p">(</span><span class="n">uv_default_loop</span><span class="p">(),</span> <span class="o">&amp;</span><span class="n">idler</span><span class="p">);</span>
    <span class="n">uv_idle_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">idler</span><span class="p">,</span> <span class="n">idle_cb</span><span class="p">);</span>

    <span class="n">uv_prepare_init</span><span class="p">(</span><span class="n">uv_default_loop</span><span class="p">(),</span> <span class="o">&amp;</span><span class="n">prep</span><span class="p">);</span>
    <span class="n">uv_prepare_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">prep</span><span class="p">,</span> <span class="n">prep_cb</span><span class="p">);</span>

    <span class="n">uv_run</span><span class="p">(</span><span class="n">uv_default_loop</span><span class="p">(),</span> <span class="n">UV_RUN_DEFAULT</span><span class="p">);</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../index.html">
              <img class="logo" src="../_static/logo.png" alt="Logo"/>
            </a></p>
  <h3><a href="../index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Advanced event loops</a><ul>
<li><a class="reference internal" href="#stopping-an-event-loop">Stopping an event loop</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="processes.html"
                        title="previous chapter">Processes</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="utilities.html"
                        title="next chapter">Utilities</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/guide/eventloops.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" />
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="utilities.html" title="Utilities"
             >next</a> |</li>
        <li class="right" >
          <a href="processes.html" title="Processes"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">libuv 1.31.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../guide.html" >User guide</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Advanced event loops</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2014-present, libuv contributors.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
    </div>
  </body>
</html>